"""

Copyright MUAMP 2021 MUAMP.COM David French

This Circuit Python code to control the Robot Quadruped "PICO Python Dog" can be freely used and modified, providing:

This code must NOT be used for commercial use or for profit.

This comment must remain in the code at the top of the .py file and this comment must NOT be modified or removed.

"""


import time

import board

import busio

import pwmio

from adafruit_motor import servo

import adafruit_icm20x

from math import asin, acos, atan, degrees, sqrt

import pulseio

import adafruit_irremote



# IR sensor

IR_PIN = board.GP9 # Pin GP9 connected to IR receiver

# IR decoder

pulsein = pulseio.PulseIn(IR_PIN, maxlen=100, idle_state=True)

decoder = adafruit_irremote.GenericDecode()

pulsein.clear()

pulsein.resume()


# Acc Gyro Mag test setup on i2c (1)

i2c = busio.I2C(board.GP11, board.GP10)

icm = adafruit_icm20x.ICM20948(i2c)


# AGM functions

def Acc(): # Acc +/- 10 for 90 degrees of x and y axis (wobble board +...)

Ax = round(icm.acceleration[0]) # Gyro detects sudden movement in real time (compliance +...)

Ay = round(icm.acceleration[1]) # Mag (compass) for up side down detection

return Ax, Ay


# Servo setup (Raspberry Pi PICO micro controller (Circuit Python) with Tower Pro MG90S servos

FL_knee = servo.Servo(pwmio.PWMOut(board.GP0, duty_cycle=0, frequency=50), min_pulse=500, max_pulse=2400)

FL_hip = servo.Servo(pwmio.PWMOut(board.GP1, duty_cycle=0, frequency=50), min_pulse=500, max_pulse=2400)

FR_knee = servo.Servo(pwmio.PWMOut(board.GP27, duty_cycle=0, frequency=50), min_pulse=500, max_pulse=2400)

FR_hip = servo.Servo(pwmio.PWMOut(board.GP26, duty_cycle=0, frequency=50), min_pulse=500, max_pulse=2400)

BL_knee = servo.Servo(pwmio.PWMOut(board.GP14, duty_cycle=0, frequency=50), min_pulse=500, max_pulse=2400)

BL_hip = servo.Servo(pwmio.PWMOut(board.GP15, duty_cycle=0, frequency=50), min_pulse=500, max_pulse=2400)

BR_knee = servo.Servo(pwmio.PWMOut(board.GP21, duty_cycle=0, frequency=50), min_pulse=500, max_pulse=2400)

BR_hip = servo.Servo(pwmio.PWMOut(board.GP20, duty_cycle=0, frequency=50), min_pulse=500, max_pulse=2400)


# servo function - converts Cartesian inputs to degrees of angles of servos

def leg_control(FLx,FLy,FRx,FRy,BLx,BLy,BRx,BRy):


FRcal = -5 # calibration factor


FLhip, FLknee = rec2pol(FLx, FLy) # This IK code is interpolated by default!

FRhip, FRknee = rec2pol(FRx, FRy)

BLhip, BLknee = rec2pol(BLx, BLy)

BRhip, BRknee = rec2pol(BRx, BRy)


# degrees do NOT have to be integers

FL_knee.angle = 180 - FLknee

FL_hip.angle = 180 - FLhip

FR_knee.angle = FRknee + FRcal

FR_hip.angle = FRhip

BL_knee.angle = 180 - BLknee

BL_hip.angle = 180 - BLhip

BR_knee.angle = BRknee

BR_hip.angle = BRhip



def rec2pol(x,y): # upper and lower leg are both 50mm

hypotenuse = sqrt(y**2+x**2)

hip = 90+(degrees((atan(x/y))-acos(((hypotenuse**2)/(100*hypotenuse)))))

knee = degrees(acos(1-((hypotenuse**2)/5000)))

return hip, knee



def numbers(start, finish): # list of numbers from 'start' to 'finish' for smooth linear leg movement

numbers = []

if start < finish:

for new_number in range(start, finish, 1):

for fraction in range(0, 10, 2):

value = new_number + fraction/10

numbers.append(value)

else:

for new_number in range(start-1, finish-1, -1):

for fraction in range(10, 0, -2):

value = new_number + fraction/10

numbers.append(value)

numbers.append(finish+0.0)

return numbers



""" MAIN CODE """


time.sleep(3)

# CRAWL

# leg_control(FLx, FLy, FRx, FRy, BLx, BLy, BRx, BRy)


delay = 0.002


while True:

leg_control(-40, 60, 40, 60, 40, 60, -40, 60)

time.sleep(delay)

leg_control(-39, 59.4, 39, 60, 39, 60, -39, 59.4)

time.sleep(delay)

leg_control(-38, 58.6, 38, 60, 38, 60, -38, 58.6)

time.sleep(delay)

leg_control(-37, 57.8, 37, 60, 37, 60, -37, 57.8)

time.sleep(delay)

leg_control(-36, 57, 36, 60, 36, 60, -36, 57)

time.sleep(delay)

leg_control(-35, 56.3, 35, 60, 35, 60, -35, 56.3)

time.sleep(delay)

leg_control(-34, 55.6, 34, 60, 34, 60, -34, 55.6)

time.sleep(delay)

leg_control(-33, 54.9, 33, 60, 33, 60, -33, 54.9)

time.sleep(delay)

leg_control(-32, 54.2, 32, 60, 32, 60, -32, 54.2)

time.sleep(delay)

leg_control(-31, 53.6, 31, 60, 31, 60, -31, 53.6)

time.sleep(delay)

leg_control(-30, 53, 30, 60, 30, 60, -30, 53)

time.sleep(delay)

leg_control(-29, 52.5, 29, 60, 29, 60, -29, 52.5)

time.sleep(delay)

leg_control(-28, 51.9, 28, 60, 28, 60, -28, 51.9)

time.sleep(delay)

leg_control(-27, 51.4, 27, 60, 27, 60, -27, 51.4)

time.sleep(delay)

leg_control(-26, 50.9, 26, 60, 26, 60, -26, 50.9)

time.sleep(delay)

leg_control(-25, 50.5, 25, 60, 25, 60, -25, 50.5)

time.sleep(delay)

leg_control(-24, 50, 24, 60, 24, 60, -24, 50)

time.sleep(delay)

leg_control(-23, 49.6, 23, 60, 23, 60, -23, 49.6)

time.sleep(delay)

leg_control(-22, 49.2, 22, 60, 22, 60, -22, 49.2)

time.sleep(delay)

leg_control(-21, 48.8, 21, 60, 21, 60, -21, 48.8)

time.sleep(delay)

leg_control(-20, 48.4, 20, 60, 20, 60, -20, 48.4)

time.sleep(delay)

leg_control(-19, 48.1, 19, 60, 19, 60, -19, 48.1)

time.sleep(delay)

leg_control(-18, 47.8, 18, 60, 18, 60, -18, 47.8)

time.sleep(delay)

leg_control(-17, 47.5, 17, 60, 17, 60, -17, 47.5)

time.sleep(delay)

leg_control(-16, 47.2, 16, 60, 16, 60, -16, 47.2)

time.sleep(delay)

leg_control(-15, 46.9, 15, 60, 15, 60, -15, 46.9)

time.sleep(delay)

leg_control(-14, 46.7, 14, 60, 14, 60, -14, 46.7)

time.sleep(delay)

leg_control(-13, 46.4, 13, 60, 13, 60, -13, 46.4)

time.sleep(delay)

leg_control(-12, 46.2, 12, 60, 12, 60, -12, 46.2)

time.sleep(delay)

leg_control(-11, 46, 11, 60, 11, 60, -11, 46)

time.sleep(delay)

leg_control(-10, 45.8, 10, 60, 10, 60, -10, 45.8)

time.sleep(delay)

leg_control(-9, 45.7, 9, 60, 9, 60, -9, 45.7)

time.sleep(delay)

leg_control(-8, 45.5, 8, 60, 8, 60, -8, 45.5)

time.sleep(delay)

leg_control(-7, 45.4, 7, 60, 7, 60, -7, 45.4)

time.sleep(delay)

leg_control(-6, 45.3, 6, 60, 6, 60, -6, 45.3)

time.sleep(delay)

leg_control(-5, 45.2, 5, 60, 5, 60, -5, 45.2)

time.sleep(delay)

leg_control(-4, 45.1, 4, 60, 4, 60, -4, 45.1)

time.sleep(delay)

leg_control(-3, 45.1, 3, 60, 3, 60, -3, 45.1)

time.sleep(delay)

leg_control(-2, 45, 2, 60, 2, 60, -2, 45)

time.sleep(delay)

leg_control(-1, 45, 1, 60, 1, 60, -1, 45)

time.sleep(delay)

leg_control(0, 45, 0, 60, 0, 60, 0, 45)

time.sleep(delay)

leg_control(1, 45, -1, 60, -1, 60, 1, 45)

time.sleep(delay)

leg_control(2, 45, -2, 60, -2, 60, 2, 45)

time.sleep(delay)

leg_control(3, 45.1, -3, 60, -3, 60, 3, 45.1)

time.sleep(delay)

leg_control(4, 45.1, -4, 60, -4, 60, 4, 45.1)

time.sleep(delay)

leg_control(5, 45.2, -5, 60, -5, 60, 5, 45.2)

time.sleep(delay)

leg_control(6, 45.3, -6, 60, -6, 60, 6, 45.3)

time.sleep(delay)

leg_control(7, 45.4, -7, 60, -7, 60, 7, 45.4)

time.sleep(delay)

leg_control(8, 45.5, -8, 60, -8, 60, 8, 45.5)

time.sleep(delay)

leg_control(9, 45.7, -9, 60, -9, 60, 9, 45.7)

time.sleep(delay)

leg_control(10, 45.8, -10, 60, -10, 60, 10, 45.8)

time.sleep(delay)

leg_control(11, 46, -11, 60, -11, 60, 11, 46)

time.sleep(delay)

leg_control(12, 46.2, -12, 60, -12, 60, 12, 46.2)

time.sleep(delay)

leg_control(13, 46.4, -13, 60, -13, 60, 13, 46.4)

time.sleep(delay)

leg_control(14, 46.7, -14, 60, -14, 60, 14, 46.7)

time.sleep(delay)

leg_control(15, 46.9, -15, 60, -15, 60, 15, 46.9)

time.sleep(delay)

leg_control(16, 47.2, -16, 60, -16, 60, 16, 47.2)

time.sleep(delay)

leg_control(17, 47.5, -17, 60, -17, 60, 17, 47.5)

time.sleep(delay)

leg_control(18, 47.8, -18, 60, -18, 60, 18, 47.8)

time.sleep(delay)

leg_control(19, 48.1, -19, 60, -19, 60, 19, 48.1)

time.sleep(delay)

leg_control(20, 48.4, -20, 60, -20, 60, 20, 48.4)

time.sleep(delay)

leg_control(21, 48.8, -21, 60, -21, 60, 21, 48.8)

time.sleep(delay)

leg_control(22, 49.2, -22, 60, -22, 60, 22, 49.2)

time.sleep(delay)

leg_control(23, 49.6, -23, 60, -23, 60, 23, 49.6)

time.sleep(delay)

leg_control(24, 50, -24, 60, -24, 60, 24, 50)

time.sleep(delay)

leg_control(25, 50.5, -25, 60, -25, 60, 25, 50.5)

time.sleep(delay)

leg_control(26, 50.9, -26, 60, -26, 60, 26, 50.9)

time.sleep(delay)

leg_control(27, 51.4, -27, 60, -27, 60, 27, 51.4)

time.sleep(delay)

leg_control(28, 51.9, -28, 60, -28, 60, 28, 51.9)

time.sleep(delay)

leg_control(29, 52.5, -29, 60, -29, 60, 29, 52.5)

time.sleep(delay)

leg_control(30, 53, -30, 60, -30, 60, 30, 53)

time.sleep(delay)

leg_control(31, 53.6, -31, 60, -31, 60, 31, 53.6)

time.sleep(delay)

leg_control(32, 54.2, -32, 60, -32, 60, 32, 54.2)

time.sleep(delay)

leg_control(33, 54.9, -33, 60, -33, 60, 33, 54.9)

time.sleep(delay)

leg_control(34, 55.6, -34, 60, -34, 60, 34, 55.6)

time.sleep(delay)

leg_control(35, 56.3, -35, 60, -35, 60, 35, 56.3)

time.sleep(delay)

leg_control(36, 57, -36, 60, -36, 60, 36, 57)

time.sleep(delay)

leg_control(37, 57.8, -37, 60, -37, 60, 37, 57.8)

time.sleep(delay)

leg_control(38, 58.6, -38, 60, -38, 60, 38, 58.6)

time.sleep(delay)

leg_control(39, 59.4, -39, 60, -39, 60, 39, 59.4)

time.sleep(delay)

leg_control(40, 60, -40, 60, -40, 60, 40, 60)

time.sleep(delay)

# half way point

leg_control(40, 60, -40, 60, -40, 60, 40, 60)

time.sleep(delay)

leg_control(39, 60, -39, 59.4, -39, 59.4, 39, 60)

time.sleep(delay)

leg_control(38, 60, -38, 58.6, -38, 58.6, 38, 60)

time.sleep(delay)

leg_control(37, 60, -37, 57.8, -37, 57.8, 37, 60)

time.sleep(delay)

leg_control(36, 60, -36, 57, -36, 57, 36, 60)

time.sleep(delay)

leg_control(35, 60, -35, 56.3, -35, 56.3, 35, 60)

time.sleep(delay)

leg_control(34, 60, -34, 55.6, -34, 55.6, 34, 60)

time.sleep(delay)

leg_control(33, 60, -33, 54.9, -33, 54.9, 33, 60)

time.sleep(delay)

leg_control(32, 60, -32, 54.2, -32, 54.2, 32, 60)

time.sleep(delay)

leg_control(31, 60, -31, 53.6, -31, 53.6, 31, 60)

time.sleep(delay)

leg_control(30, 60, -30, 53, -30, 53, 30, 60)

time.sleep(delay)

leg_control(29, 60, -29, 52.5, -29, 52.5, 29, 60)

time.sleep(delay)

leg_control(28, 60, -28, 51.9, -28, 51.9, 28, 60)

time.sleep(delay)

leg_control(27, 60, -27, 51.4, -27, 51.4, 27, 60)

time.sleep(delay)

leg_control(26, 60, -26, 50.9, -26, 50.9, 26, 60)

time.sleep(delay)

leg_control(25, 60, -25, 50.5, -25, 50.5, 25, 60)

time.sleep(delay)

leg_control(24, 60, -24, 50, -24, 50, 24, 60)

time.sleep(delay)

leg_control(23, 60, -23, 49.6, -23, 49.6, 23, 60)

time.sleep(delay)

leg_control(22, 60, -22, 49.2, -22, 49.2, 22, 60)

time.sleep(delay)

leg_control(21, 60, -21, 48.8, -21, 48.8, 21, 60)

time.sleep(delay)

leg_control(20, 60, -20, 48.4, -20, 48.4, 20, 60)

time.sleep(delay)

leg_control(19, 60, -19, 48.1, -19, 48.1, 19, 60)

time.sleep(delay)

leg_control(18, 60, -18, 47.8, -18, 47.8, 18, 60)

time.sleep(delay)

leg_control(17, 60, -17, 47.5, -17, 47.5, 17, 60)

time.sleep(delay)

leg_control(16, 60, -16, 47.2, -16, 47.2, 16, 60)

time.sleep(delay)

leg_control(15, 60, -15, 46.9, -15, 46.9, 15, 60)

time.sleep(delay)

leg_control(14, 60, -14, 46.7, -14, 46.7, 14, 60)

time.sleep(delay)

leg_control(13, 60, -13, 46.4, -13, 46.4, 13, 60)

time.sleep(delay)

leg_control(12, 60, -12, 46.2, -12, 46.2, 12, 60)

time.sleep(delay)

leg_control(11, 60, -11, 46, -11, 46, 11, 60)

time.sleep(delay)

leg_control(10, 60, -10, 45.8, -10, 45.8, 10, 60)

time.sleep(delay)

leg_control(9, 60, -9, 45.7, -9, 45.7, 9, 60)

time.sleep(delay)

leg_control(8, 60, -8, 45.5, -8, 45.5, 8, 60)

time.sleep(delay)

leg_control(7, 60, -7, 45.4, -7, 45.4, 7, 60)

time.sleep(delay)

leg_control(6, 60, -6, 45.3, -6, 45.3, 6, 60)

time.sleep(delay)

leg_control(5, 60, -5, 45.2, -5, 45.2, 5, 60)

time.sleep(delay)

leg_control(4, 60, -4, 45.1, -4, 45.1, 4, 60)

time.sleep(delay)

leg_control(3, 60, -3, 45.1, -3, 45.1, 3, 60)

time.sleep(delay)

leg_control(2, 60, -2, 45, -2, 45, 2, 60)

time.sleep(delay)

leg_control(1, 60, -1, 45, -1, 45, 1, 60)

time.sleep(delay)

leg_control(0, 60, 0, 45, 0, 45, 0, 60)

time.sleep(delay)

leg_control(-1, 60, 1, 45, 1, 45, -1, 60)

time.sleep(delay)

leg_control(-2, 60, 2, 45, 2, 45, -2, 60)

time.sleep(delay)

leg_control(-3, 60, 3, 45.1, 3, 45.1, -3, 60)

time.sleep(delay)

leg_control(-4, 60, 4, 45.1, 4, 45.1, -4, 60)

time.sleep(delay)

leg_control(-5, 60, 5, 45.2, 5, 45.2, -5, 60)

time.sleep(delay)

leg_control(-6, 60, 6, 45.3, 6, 45.3, -6, 60)

time.sleep(delay)

leg_control(-7, 60, 7, 45.4, 7, 45.4, -7, 60)

time.sleep(delay)

leg_control(-8, 60, 8, 45.5, 8, 45.5, -8, 60)

time.sleep(delay)

leg_control(-9, 60, 9, 45.7, 9, 45.7, -9, 60)

time.sleep(delay)

leg_control(-10, 60, 10, 45.8, 10, 45.8, -10, 60)

time.sleep(delay)

leg_control(-11, 60, 11, 46, 11, 46, -11, 60)

time.sleep(delay)

leg_control(-12, 60, 12, 46.2, 12, 46.2, -12, 60)

time.sleep(delay)

leg_control(-13, 60, 13, 46.4, 13, 46.4, -13, 60)

time.sleep(delay)

leg_control(-14, 60, 14, 46.7, 14, 46.7, -14, 60)

time.sleep(delay)

leg_control(-15, 60, 15, 46.9, 15, 46.9, -15, 60)

time.sleep(delay)

leg_control(-16, 60, 16, 47.2, 16, 47.2, -16, 60)

time.sleep(delay)

leg_control(-17, 60, 17, 47.5, 17, 47.5, -17, 60)

time.sleep(delay)

leg_control(-18, 60, 18, 47.8, 18, 47.8, -18, 60)

time.sleep(delay)

leg_control(-19, 60, 19, 48.1, 19, 48.1, -19, 60)

time.sleep(delay)

leg_control(-20, 60, 20, 48.4, 20, 48.4, -20, 60)

time.sleep(delay)

leg_control(-21, 60, 21, 48.8, 21, 48.8, -21, 60)

time.sleep(delay)

leg_control(-22, 60, 22, 49.2, 22, 49.2, -22, 60)

time.sleep(delay)

leg_control(-23, 60, 23, 49.6, 23, 49.6, -23, 60)

time.sleep(delay)

leg_control(-24, 60, 24, 50, 24, 50, -24, 60)

time.sleep(delay)

leg_control(-25, 60, 25, 50.5, 25, 50.5, -25, 60)

time.sleep(delay)

leg_control(-26, 60, 26, 50.9, 26, 50.9, -26, 60)

time.sleep(delay)

leg_control(-27, 60, 27, 51.4, 27, 51.4, -27, 60)

time.sleep(delay)

leg_control(-28, 60, 28, 51.9, 28, 51.9, -28, 60)

time.sleep(delay)

leg_control(-29, 60, 29, 52.5, 29, 52.5, -29, 60)

time.sleep(delay)

leg_control(-30, 60, 30, 53, 30, 53, -30, 60)

time.sleep(delay)

leg_control(-31, 60, 31, 53.6, 31, 53.6, -31, 60)

time.sleep(delay)

leg_control(-32, 60, 32, 54.2, 32, 54.2, -32, 60)

time.sleep(delay)

leg_control(-33, 60, 33, 54.9, 33, 54.9, -33, 60)

time.sleep(delay)

leg_control(-34, 60, 34, 55.6, 34, 55.6, -34, 60)

time.sleep(delay)

leg_control(-35, 60, 35, 56.3, 35, 56.3, -35, 60)

time.sleep(delay)

leg_control(-36, 60, 36, 57, 36, 57, -36, 60)

time.sleep(delay)

leg_control(-37, 60, 37, 57.8, 37, 57.8, -37, 60)

time.sleep(delay)

leg_control(-38, 60, 38, 58.6, 38, 58.6, -38, 60)

time.sleep(delay)

leg_control(-39, 60, 39, 59.4, 39, 59.4, -39, 60)

time.sleep(delay)

leg_control(-40, 60, 40, 60, 40, 60, -40, 60)

time.sleep(delay)